package com.ssy.lingxi.order.serviceimpl.web;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.constant.basic.FundModeEnum;
import com.ssy.lingxi.common.constant.basic.UserLoginSourceEnum;
import com.ssy.lingxi.common.constant.manage.ShopTypeEnum;
import com.ssy.lingxi.common.constant.order.*;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.order.entity.*;
import com.ssy.lingxi.order.model.bo.*;
import com.ssy.lingxi.order.model.constant.*;
import com.ssy.lingxi.order.model.dto.*;
import com.ssy.lingxi.order.model.vo.basic.request.*;
import com.ssy.lingxi.order.model.vo.basic.response.*;
import com.ssy.lingxi.order.model.vo.buyer.request.*;
import com.ssy.lingxi.order.model.vo.buyer.response.*;
import com.ssy.lingxi.order.repository.BaseOrderTimeParamRepository;
import com.ssy.lingxi.order.repository.OrderInvoiceRepository;
import com.ssy.lingxi.order.repository.OrderRepository;
import com.ssy.lingxi.order.repository.SellDeliveryGoodsRepository;
import com.ssy.lingxi.order.service.base.*;
import com.ssy.lingxi.order.service.feign.ILogisticsFeignService;
import com.ssy.lingxi.order.service.feign.IPurchaseFeignService;
import com.ssy.lingxi.order.service.web.IBuyerOrderService;
import com.ssy.lingxi.order.service.web.IDeliveryPlanService;
import com.ssy.lingxi.order.service.web.IOrderCreationService;
import com.ssy.lingxi.order.service.web.IOrderTimeParamService;
import com.ssy.lingxi.order.utils.NumberUtil;
import org.apache.poi.ss.usermodel.CellStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 采购订单相关接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2021-07-20
 */
@Service
public class BuyerOrderServiceImpl implements IBuyerOrderService {
    private final static Logger logger = LoggerFactory.getLogger(BuyerOrderServiceImpl.class);

    @Resource
    private IBaseCacheService baseCacheService;

    @Resource
    private IBaseOrderService baseOrderService;

    @Resource
    private IBaseOrderAuthService baseOrderAuthService;

    @Resource
    private IBaseOrderTaskService baseOrderTaskService;

    @Resource
    private IOrderCreationService orderCreationService;

    @Resource
    private IBaseOrderProcessService baseOrderProcessService;

    @Resource
    private IBaseOrderPaymentService baseOrderPaymentService;

    @Resource
    private IBaseOrderProductService baseOrderProductService;

    @Resource
    private IBaseOrderDeliveryService baseOrderDeliveryService;

    @Resource
    private IBaseOrderHistoryService baseOrderHistoryService;

    @Resource
    private IBaseOrderScheduleService baseOrderScheduleService;

    @Resource
    private OrderRepository orderRepository;

    @Resource
    private BaseOrderTimeParamRepository orderTimeParamRepository;

    @Resource
    private IOrderTimeParamService orderTimeParamService;

    @Resource
    private IPurchaseFeignService purchaseFeignService;

    @Resource
    private IBaseOrderConsigneeService baseOrderConsigneeService;

    @Resource
    private IBaseOrderPromotionService baseOrderPromotionService;

    @Resource
    private OrderInvoiceRepository orderInvoiceRepository;

    @Resource
    private SellDeliveryGoodsRepository sellDeliveryGoodsRepository;

    @Resource
    private IBasePlatformPaymentTypeService basePlatformPaymentTypeService;

    @Resource
    private IBaseOrderDeductionService baseOrderDeductionService;

    @Resource
    private ILogisticsFeignService logisticsFeignService;

    @Resource
    private IDeliveryPlanService deliveryPlanService;


    /**
     * （待分配订单页面） 获取前端页面下拉框列表
     *
     * @param headers Http头部信息
     * @return 查询结果
     */
    @Override
    public Wrapper<List<DropdownItem>> getTakePageItems(HttpHeaders headers) {
        return Wrapper.success(baseOrderService.listOrderTypes());
    }

    /**
     * “待分配订单” - 查询订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BaseBuyerOrderQueryVO>> pageToTakeOrders(HttpHeaders headers, OrderPageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        Page<OrderDO> pageList = baseOrderService.pageBuyerToTakeOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BaseBuyerOrderQueryVO queryVO = new BaseBuyerOrderQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setVendorMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setDeliverAddress(baseOrderConsigneeService.orderConsigneeToString(order.getConsignee()));
            queryVO.setQuoteNo(order.getQuoteNo());
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待分配订单” - 订单详情
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerOrderDetailVO> getToTakeOrderDetail(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        return baseOrderService.getBuyerOrderDetail(order);
    }

    /**
     * “待分配订单” - 领取订单
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> takeOrder(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //判断是否已经被领取
        if(!baseOrderService.canBuyerTakeOrder(order)) {
            return Wrapper.fail(ResponseCode.ORDER_HAS_BEEN_TAKEN);
        }

        order.setBuyerUserId(loginUser.getUserId());
        orderRepository.saveAndFlush(order);
        return Wrapper.success();
    }

    /**
     * “待分配订单” - 批量领取订单
     *
     * @param headers  Http头部信息
     * @param orderIds 订单Id列表
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> batchTakeOrders(HttpHeaders headers, List<OrderIdVO> orderIds) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        if(CollectionUtils.isEmpty(orderIds)) {
            return Wrapper.success();
        }

        List<OrderDO> orders = orderRepository.findAllById(orderIds.stream().map(OrderIdVO::getOrderId).collect(Collectors.toList()));
        if(orders.size() != orderIds.size() || orders.stream().anyMatch(order -> !order.getBuyerMemberId().equals(loginUser.getMemberId()) && !order.getBuyerRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        if(orders.stream().anyMatch(order -> !baseOrderService.canBuyerTakeOrder(order))) {
            return Wrapper.fail(ResponseCode.ORDER_HAS_BEEN_TAKEN);
        }

        orders.forEach(order -> order.setBuyerUserId(loginUser.getUserId()));
        orderRepository.saveAll(orders);
        return Wrapper.success();
    }

    /**
     * 获取前端页面下拉框列表
     *
     * @param headers Http头部信息
     * @return 查询结果
     */
    @Override
    public Wrapper<PageItemVO> getPageItems(HttpHeaders headers) {
        baseCacheService.needLoginFromBusinessPlatform(headers);
        PageItemVO itemVO = new PageItemVO();
        itemVO.setInnerStatus(BuyerInnerStatusEnum.toDropdownList());
        itemVO.setOuterStatus(OrderOuterStatusEnum.toDropdownList());
        itemVO.setOrderTypes(baseOrderService.listOrderTypes());
        return Wrapper.success(itemVO);
    }

    /**
     * 分页查询订单
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BuyerOrderQueryVO>> pageOrders(HttpHeaders headers, OrderManagePageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        Page<OrderDO> pageList = baseOrderService.pageBuyerOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), pageVO.getInnerStatus(), pageVO.getOuterStatus(), pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerOrderQueryVO queryVO = new BuyerOrderQueryVO();
            queryVO.setShopId(order.getShopId());
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setVendorMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setDeliverAddress(baseOrderConsigneeService.orderConsigneeToString(order.getConsignee()));
            queryVO.setQuoteNo(order.getQuoteNo());
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            //按钮显示
            queryVO.setShowAfterSales(baseOrderService.canAfterSaleOrder(order));
            queryVO.setShowComment(baseOrderService.canBuyerCommentOrder(order));
            queryVO.setShowCancel(baseOrderService.canBuyerCancelOrder(order));
            queryVO.setShowModifyDeliverTime(baseOrderService.canBuyerModifyDeliverTime(order));
            queryVO.setShowRefund(baseOrderService.canBuyerRefundOrder(order));
            queryVO.setShowDelete(baseOrderService.canBuyerDeleteOrder(order));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 订单退款
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 退款结果
     */
    @Override
    public Wrapper<Void> orderRefund(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return orderRefund(loginUser, idVO);
    }

    /**
     * 订单退款
     *
     * @param loginUser 订单退款
     * @param idVO      接口参数
     * @return 退款结果
     */
    @Override
    public Wrapper<Void> orderRefund(UserLoginCacheDTO loginUser, OrderIdVO idVO) {
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        Wrapper<Void> result = baseOrderPaymentService.groupOrderRefund(order);
        if(result.getCode() == ResponseCode.SUCCESS.getCode()) {
            //订单内、外流转记录
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.REFUND, order.getBuyerInnerStatus(), "");
            baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.REFUND, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            //将订单未发货的数量返回库存
            Wrapper<Void> resumeResult = baseOrderService.resumeInventory(order);
            if (resumeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                logger.error("退款成功返还库存失败，code:" + resumeResult.getCode() + ", msg:" + resumeResult.getMessage());
                return Wrapper.success();
            }
        }

        return result;
    }

    /**
     * 分页查询订单 - 订单删除
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> pageOrderDelete(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return pageOrderDelete(loginUser, idVO);
    }

    /**
     * 分页查询订单 - 订单删除
     * @param loginUser 用户信息
     * @param idVO      接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> pageOrderDelete(UserLoginCacheDTO loginUser, OrderIdVO idVO) {
        orderRepository.deleteById(idVO.getOrderId());
        return Wrapper.success();
    }

    /**
     * 订单详情
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerOrderDetailVO> getOrderDetail(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }
        if(!order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_WRONG_ROLE);
        }

        return baseOrderService.getBuyerOrderDetail(order);
    }

    /**
     * 采购订单详情 - 申请开票
     * @param headers Http头部信息
     * @param invoiceVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> applyInvoice(HttpHeaders headers, BuyerApplyInvoiceVO invoiceVO) {
        baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(invoiceVO.getOrderId()).orElse(null);
        if (order == null) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }
        orderInvoiceRepository.deleteByOrder(order);

        OrderInvoiceDO invoice = new OrderInvoiceDO();
        invoice.setInvoiceId(invoiceVO.getInvoiceId());
        invoice.setOrder(order);
        invoice.setInvoiceKind(invoiceVO.getInvoiceKind());
        invoice.setInvoiceType(invoiceVO.getInvoiceType());
        invoice.setTitle(invoiceVO.getTitle());
        invoice.setTaxNo(StringUtils.hasLength(invoiceVO.getTaxNo()) ? invoiceVO.getTaxNo() : "");
        invoice.setBank(StringUtils.hasLength(invoiceVO.getBank()) ? invoiceVO.getBank().trim() : "");
        invoice.setAccount(StringUtils.hasLength(invoiceVO.getAccount()) ? invoiceVO.getAccount().trim() : "");
        invoice.setAddress(StringUtils.hasLength(invoiceVO.getAddress()) ? invoiceVO.getAddress().trim() : "");
        invoice.setPhone(StringUtils.hasLength(invoiceVO.getPhone()) ? invoiceVO.getPhone().trim() : "");
        invoice.setDefaultInvoice(true);

        order.setInvoice(invoice);
        orderRepository.save(order);

        return Wrapper.success();
    }

    /**
     * 取消订单
     *
     * @param headers  Http头部信息
     * @param reasonVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> cancelOrder(HttpHeaders headers, OrderReasonVO reasonVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return cancelOrder(loginUser, reasonVO);
    }

    /**
     * 根据供应商会员信息和商城id获取预约时长和配置配送时间段
     * @param headers HttpHeaders信息
     * @param deliveryDateVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<OrderDeliveryDateVO> findBuyerDeliveryDate(HttpHeaders headers, DeliveryDateVO deliveryDateVO) {
        baseCacheService.needLoginFromBusinessPlatform(headers);
        return orderTimeParamService.findBuyerDeliveryDate(deliveryDateVO.getVendorMemberId(), deliveryDateVO.getVendorRoleId(), deliveryDateVO.getShopId());
    }

    /**
     * 查看订单送货时间
     * @param headers Http头部信息
     * @param timeVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<OrderDeliverTimeDetailVO> getDeliveryTime(HttpHeaders headers, BuyerOrderDeliveryTimeVO timeVO) {
        baseCacheService.needLoginFromBusinessPlatform(headers);

        OrderDO order = orderRepository.findById(timeVO.getOrderId()).orElse(null);
        if (order == null) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //订单送货时间段
        OrderDeliverTimeDetailVO vo = new OrderDeliverTimeDetailVO();
        String deliverPeriod = order.getDeliverPeriod();
        vo.setDeliverDate(deliverPeriod);

        if (StrUtil.isNotEmpty(deliverPeriod)) {
            String deliveryTime = deliverPeriod.concat(" ").concat("00:00");
            boolean isPeriod = deliveryTime.split(" ")[1].contains("-");
            if (isPeriod) {
                vo.setDeliverDate(deliveryTime.split(" ")[0]);
                vo.setDeliverPeriod(deliveryTime.split(" ")[1]);
            }
        }

        //配置的时间参数
        List<BaseOrderTimeParamDO> timeParamList = orderTimeParamRepository.findAllByMemberIdAndMemberRoleIdAndShopIdAndStatus(order.getVendorMemberId(), order.getVendorRoleId(), timeVO.getShopId(), EnableDisableStatus.ENABLE.getCode());
        //送货预约时长
        BaseOrderTimeParamDO dayParam = timeParamList.stream().filter(dateParam -> OrderTimeParamEnum.DELIVERY_APPOINTMENT_DAY.getCode().equals(dateParam.getParamType())).findFirst().orElse(null);
        if (dayParam != null) {
            vo.setAppointmentDay(true);
            vo.setDays(dayParam.getDays());
        }

        //配送时间段
        List<DeliveryTimeVO> timeParam = timeParamList.stream().filter(dateParam -> OrderTimeParamEnum.DELIVERY_TIME.getCode().equals(dateParam.getParamType()))
                .map(time -> new DeliveryTimeVO(time.getStartTime(), time.getEndTime())).sorted(Comparator.comparing(DeliveryTimeVO::getStartTime, Comparator.nullsLast(String::compareTo))).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(timeParam)) {
            vo.setDeliveryTime(true);
            vo.setParamList(timeParam);
        }

        return Wrapper.success(vo);
    }

    /**
     * 订单查询导出
     * @param token 登录token
     * @param pageVO 接口参数
     * @param response 响应体
     */
    @Override
    public void exportOrders(HttpServletResponse response, OrderManagePageVO pageVO, String token) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(token);

        //获取采购订单导出数据
        List<OrderDO> orderList = baseOrderService.exportBuyerOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), pageVO.getInnerStatus() == null ? null : Collections.singletonList(pageVO.getInnerStatus()), pageVO.getOuterStatus());

        List<Map<String, Object>> rows = orderList.stream().map(order -> {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("订单编号", order.getOrderNo());
            map.put("订单摘要", order.getDigest());
            map.put("供应会员名称", order.getVendorMemberName());
            map.put("下单时间", order.getCreateTime());
            map.put("订单总额", NumberUtil.formatAmount(order.getTotalAmount()));
            map.put("订单类型名称", OrderTypeEnum.getNameByCode(order.getOrderType()));
            map.put("外部状态名称", OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            map.put("内部状态名称", VendorInnerStatusEnum.getNameByCode(order.getVendorInnerStatus()));
            return map;
        }).collect(Collectors.toList());


        ExcelWriter writer = ExcelUtil.getBigWriter();
        CellStyle style = writer.getHeadCellStyle();
        style.setWrapText(true);
        writer.write(rows);

        String fileName = "采购订单-" + DateUtil.date() + ".xls";
        try (ServletOutputStream out = response.getOutputStream()) {
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            writer.flush(out, true);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            writer.close();
        }
    }

    /**
     * 未发货调整订单送货时间
     * @param headers Http头部信息
     * @param updateVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateDeliveryTime(HttpHeaders headers, BuyerOrderDeliveryTimeUpdateVO updateVO) {
        UserLoginCacheDTO loginUser = baseCacheService.checkUserFromCache(headers);

        OrderDO order = orderRepository.findById(updateVO.getOrderId()).orElse(null);
        if (order == null) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }
        //更新订单送货时间
        order.setDeliverPeriod(updateVO.getDeliverPeriod());
        orderRepository.saveAndFlush(order);

        //内部流转记录调整理由
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.MODIFY_DELIVER_PERIOD, order.getBuyerInnerStatus(), updateVO.getReason());
        return Wrapper.success();
    }

    /**
     * 取消订单
     *
     * @param loginUser 登录用户
     * @param reasonVO  接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> cancelOrder(UserLoginCacheDTO loginUser, OrderReasonVO reasonVO) {
        OrderDO order = orderRepository.findById(reasonVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }
        //记录采购、供应的上一次内部状态，用于发送报表统计数据
        int lastBuyerInnerStatus = order.getBuyerInnerStatus();
        //记录上一次的供应商状态，用于发送报表数据
        int lastVendorInnerStatus = order.getVendorInnerStatus();

        //判断取消条件
        if(!baseOrderService.canBuyerCancelOrder(order)) {
            return Wrapper.fail(ResponseCode.ORDER_CAN_NOT_BE_CANCEL);
        }

        //将订单未发货的数量返回库存，SRM订单、请购采购订单不需要返回库存
        Wrapper<Void> resumeResult = baseOrderService.resumeInventory(order);
        if (resumeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return resumeResult;
        }

        //返还已抵扣的积分
        Wrapper<Void> deductionResult = baseOrderDeductionService.returnDeductionPoints(order);
        if (deductionResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(ResponseCode.ORDER_POINTS_RETURN_FAIL);
        }

        order.setBuyerInnerStatus(BuyerInnerStatusEnum.CANCELLED.getCode());
        order.setVendorInnerStatus(VendorInnerStatusEnum.CANCELLED.getCode());
        order.setOuterStatus(OrderOuterStatusEnum.CANCELLED.getCode());
        orderRepository.saveAndFlush(order);



        //通知合同服务，取消SRM订单数据
        baseOrderService.cancelSrmOrder(order);

        //通知营销服务，返还营销活动、优惠券记录
        baseOrderService.resumePromotions(order);

        //内部、外部记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.CANCEL, order.getBuyerInnerStatus(), reasonVO.getReason().trim());
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.CANCEL, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), reasonVO.getReason().trim());

        //向报表服务发送统计数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatus, order.getBuyerInnerStatus());
        baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), lastVendorInnerStatus, order.getVendorInnerStatus());
        return Wrapper.success();
    }

    /**
     * “待新增订单” - 获取前端页面下拉框列表
     *
     * @param headers Http头部信息
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerToCreatePageItemVO> getToCreatePageItems(HttpHeaders headers) {
        baseCacheService.needLoginFromBusinessPlatform(headers);
        BuyerToCreatePageItemVO itemVO = new BuyerToCreatePageItemVO();
        itemVO.setOrderTypes(Stream.of(OrderTypeEnum.INQUIRY_TO_PURCHASE, OrderTypeEnum.QUERY_PRICE_CONTRACT, OrderTypeEnum.PRICE_COMPETITION_CONTRACT_PURCHASE, OrderTypeEnum.PURCHASE_CONTRACT_BIDDING).map(e -> new DropdownItem(e.getCode(), e.getName())).collect(Collectors.toList()));
        itemVO.setOrderModes(Stream.of(OrderModeEnum.QUOTATION, OrderModeEnum.PURCHASE_INQUIRY, OrderModeEnum.PURCHASE_PRICE_COMPETITION, OrderModeEnum.PURCHASE_BIDDING).map(e -> new DropdownItem(e.getCode(), e.getName())).collect(Collectors.toList()));
        return Wrapper.success(itemVO);
    }

    /**
     * “待新增订单” - 分页查询订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BuyerToCreateQueryVO>> pageToCreateOrders(HttpHeaders headers, OrderPageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderTypeEnum> orderTypes = NumberUtil.isNullOrNegativeZero(pageVO.getOrderType()) ? Stream.of(OrderTypeEnum.INQUIRY_TO_PURCHASE).collect(Collectors.toList()) : Collections.singletonList(OrderTypeEnum.parse(pageVO.getOrderType()));
        Page<OrderDO> pageList = baseOrderService.pageCreatedOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), orderTypes,  pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerToCreateQueryVO queryVO = new BuyerToCreateQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setVendorMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setQuoteNo(order.getQuoteNo());
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            queryVO.setShowUpdate(order.getSeparateType().equals(OrderSeparateTypeEnum.DEFAULT.getCode()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待新增订单” - 分页查询SRM订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BuyerToCreateQueryVO>> pageSrmOrders(HttpHeaders headers, OrderPageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderTypeEnum> orderTypes = NumberUtil.isNullOrNegativeZero(pageVO.getOrderType()) ? Stream.of(OrderTypeEnum.QUERY_PRICE_CONTRACT, OrderTypeEnum.PRICE_COMPETITION_CONTRACT_PURCHASE, OrderTypeEnum.PURCHASE_CONTRACT_BIDDING).collect(Collectors.toList()) : Collections.singletonList(OrderTypeEnum.parse(pageVO.getOrderType()));
        Page<OrderDO> pageList = baseOrderService.pageCreatedOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), orderTypes,  pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerToCreateQueryVO queryVO = new BuyerToCreateQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setVendorMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setQuoteNo(order.getQuoteNo());
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            queryVO.setShowUpdate(order.getSeparateType().equals(OrderSeparateTypeEnum.DEFAULT.getCode()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待新增订单” - 创建SRM订单
     *
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Override
    public Wrapper<Void> createSrmOrder(HttpHeaders headers, BuyerSrmOrderVO orderVO) {
        return orderCreationService.createSrmOrder(headers, orderVO);
    }

    /**
     * “待新增订单” - 查询订单详情
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerOrderDetailVO> getToCreateOrderDetails(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        return baseOrderService.getBuyerOrderDetail(order, BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE);
    }

    /**
     * “待新增订单” - 修改Srm订单
     *
     * @param headers  Http头部信息
     * @param updateVO 接口参数
     * @return 修改结果
     */
    @Override
    public Wrapper<Void> updateSrmOrder(HttpHeaders headers, BuyerSrmOrderUpdateVO updateVO) {
        return orderCreationService.updateSrmOrder(headers, updateVO);
    }

    /**
     * “待新增订单” - “创建B2B订单” - 查询支付环节列表
     *
     * @param headers Http头部信息
     * @param payVO   接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<BuyerOrderPayNodeDetailVO>> findBusinessOrderProcessPayment(HttpHeaders headers, OrderProcessPayVO payVO) {
        //Step 1: 跨境商品不能与其他商品一起下单
        List<Boolean> crossBorders = payVO.getProducts().stream().map(product -> Objects.isNull(product.getCrossBorder()) ? false : product.getCrossBorder()).distinct().collect(Collectors.toList());
        if(crossBorders.size() > 1) {
            return Wrapper.fail(ResponseCode.ORDER_PRODUCT_TRADE_PROCESS_IS_DIFFERENT);
        }

        //Step 2: 查询供应商交易流程规则
        Wrapper<OrderTradeProcessBO> tradeProcessResult = baseOrderProcessService.findVendorTradeProcess(payVO.getMemberId(), payVO.getRoleId(), payVO.getShopId(), crossBorders.get(0) ? OrderTradeProcessTypeEnum.ORDER_COMMERCE_IMPORT : OrderTradeProcessTypeEnum.ORDER_TRADE, payVO.getProducts().stream().map(productIdVO -> new OrderProductBO(productIdVO.getProductId(), productIdVO.getSkuId())).collect(Collectors.toList()));
        if(tradeProcessResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(tradeProcessResult.getCode(), tradeProcessResult.getMessage());
        }

        //Step 3: 返回支付环节配置
        return Wrapper.success(tradeProcessResult.getData().getPayNodes().stream().filter(payNode -> payNode.getPayRate().compareTo(BigDecimal.ZERO) > 0).map(payNode -> {
            BuyerOrderPayNodeDetailVO detailVO = new BuyerOrderPayNodeDetailVO();
            detailVO.setBatchNo(payNode.getBatchNo());
            detailVO.setPayNode(payNode.getPayNode());
            detailVO.setOuterStatusName(OrderOuterStatusEnum.TO_PAY.getName());
            detailVO.setPayRate(NumberUtil.formatPayRate(payNode.getPayRate()));
            return detailVO;
        }).collect(Collectors.toList()));
    }

    /**
     * “待新增订单” - “修改B2B订单” - 查询支付环节列表
     *
     * @param headers Http头部信息
     * @param updateVO   接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<BuyerOrderPayNodeQueryVO>> findBusinessOrderProcessPaymentUpdate(HttpHeaders headers, BuyerBusinessOrderProcessPayUpdateVO updateVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(updateVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1: 查询会员支付方式
        Wrapper<List<OrderPayTypeDetailVO>> payTypeResult = baseOrderProcessService.findMemberPayment(loginUser.getMemberId(), loginUser.getMemberRoleId(), updateVO.getVendorMemberId(), updateVO.getVendorRoleId());
        if(payTypeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(payTypeResult.getCode(), payTypeResult.getMessage());
        }

        //Step 2:  查询支付记录，如果会员支付方式中不包含已经有的支付记录中的支付方式和渠道，设置为Null
        List<BuyerOrderPayNodeQueryVO> payNodes = baseOrderPaymentService.findBusinessOrderPayments(order);
        payNodes.forEach(payNode -> {
            OrderPayTypeDetailVO payTypeDetail = payTypeResult.getData().stream().filter(payType -> payType.getPayType().equals(payNode.getPayType())).findFirst().orElse(null);
            if (payTypeDetail == null) {
                payNode.setPayType(null);
                payNode.setPayChannel(null);
                return;
            }

            if(payTypeDetail.getPayChannels().stream().noneMatch(payChannel -> payChannel.getPayChannel().equals(payNode.getPayChannel()))) {
                payNode.setPayChannel(null);
            }
        });

        return Wrapper.success(payNodes);
    }

    /**
     * “待新增订单” - B2B订单 - 查询支付方式与支付渠道列表
     *
     * @param headers Http头部信息
     * @param vendorMemberVO   接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<OrderPayTypeDetailVO>> findBusinessOrderPayTypes(HttpHeaders headers, OrderVendorMemberVO vendorMemberVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return baseOrderProcessService.findMemberPayment(loginUser.getMemberId(), loginUser.getMemberRoleId(), vendorMemberVO.getVendorMemberId(), vendorMemberVO.getVendorRoleId());
    }

    /**
     * “待新增订单” - 创建B2B订单
     *
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 创建结果
     */
    @Override
    public Wrapper<Void> createBusinessOrder(HttpHeaders headers, BuyerBusinessOrderVO orderVO) {
        return orderCreationService.createBusinessOrder(headers, orderVO);
    }

    /**
     * “待新增订单” - 修改B2B订单
     *
     * @param headers  Http头部信息
     * @param updateVO 接口参数
     * @return 创建结果
     */
    @Override
    public Wrapper<Void> updateBusinessOrder(HttpHeaders headers, BuyerBusinessOrderUpdateVO updateVO) {
        return orderCreationService.updateBusinessOrder(headers, updateVO);
    }

    /**
     * “待新增订单” - 删除订单
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 删除结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> deleteOrder(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //如果是转单后的订单，将原订单的关联关系取消
        if(NumberUtil.notNullOrZero(order.getRelationId()) && NumberUtil.notNullOrZero(order.getSeparateType()) && order.getSeparateType().equals(OrderSeparateTypeEnum.TRANSFERRED.getCode())) {
            OrderDO separateOrder = orderRepository.findById(order.getRelationId()).orElse(null);
            if(separateOrder != null) {
                separateOrder.setRelationId(0L);
                separateOrder.setRelationNo("");
                separateOrder.setSeparateType(OrderSeparateTypeEnum.DEFAULT.getCode());
                orderRepository.saveAndFlush(separateOrder);
            }
        }

        orderRepository.delete(order);
        return Wrapper.success();
    }

    /**
     * “待新增订单” - 批量删除订单
     *
     * @param headers  Http头部信息
     * @param orderIds 接口参数
     * @return 删除结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> batchDeleteOrder(HttpHeaders headers, List<OrderIdVO> orderIds) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderDO> orders = orderRepository.findAllById(orderIds.stream().map(OrderIdVO::getOrderId).distinct().collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(orders) || orderIds.size() != orders.size() || orders.stream().anyMatch(order -> !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        orderRepository.deleteAll(orders);
        return Wrapper.success();
    }

    /**
     * “待新增订单” - 提交
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 删除结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> submitOrder(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //请购单订单扣减请购单数量、增加已转订单数量
        Wrapper<Void> quantityDeductResult = purchaseFeignService.requisitionQuantityDeduct(order);
        if (quantityDeductResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(quantityDeductResult.getCode(), quantityDeductResult.getMessage());
        }

        //Step 0: 查询供应商业务员Id
        Wrapper<Long> salesResult = baseOrderAuthService.findVendorSalesUserId(order.getBuyerMemberId(), order.getBuyerRoleId(), order.getVendorMemberId(), order.getVendorRoleId());
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        //Step 1: 非Srm订单扣减库存
        Wrapper<Void> deduceResult = baseOrderService.deduceInventory(order);
        if(deduceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(deduceResult.getCode(), deduceResult.getMessage());
        }

        //Step 2 : 执行工作流任务（修改订单状态、记录内外流转记录）
        int lastBuyerInnerStatus = order.getBuyerInnerStatus();
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order);
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            //返还库存
            baseOrderService.resumeInventory(order);
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        //Step 3: 以外部状态“待提交”作判断，订单是否已经提交给供应商
        //        如果外部状态为“待提交”，表示订单处于采购商审核过程中，否则表示订单已经提交给了“供应商”
        if(baseOrderService.hasSubmittedToVendor(order)) {
            //Step 3-1: 订单提交时间与供应商用户Id
            order.setSubmitTime(LocalDateTime.now());
            order.setVendorUserId(salesResult.getData());

            //Step 3-2: 同步Srm订单数据至合同服务
            baseOrderService.sendSrmOrder(order);

            //Step 3-3 : 订单外部流转记录
            baseOrderHistoryService.saveVendorOrderOuterHistory(order.getId(), order.getOrderNo(), order.getVendorMemberId(), order.getVendorRoleId(), order.getVendorMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            //Step 3-4 : 通知报表服务统计采购、供应双方的数据
            baseOrderService.reportVendorOrderAmount(order);

            //Step 3-5 : 统计供应商的数据
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

            //Step 3-6 : 发送供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

            //Step 3-7 ： 供应商交易流程规则配置中的自动取消
            baseOrderScheduleService.scheduleOrderCancel(order.getId(), order.getTask() == null ? BigDecimal.ZERO : order.getTask().getExpireHours());

            //Step 4 : 订单内部流转记录的操作为“提交”
            baseOrderHistoryService.saveVendorInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.SUBMIT, order.getVendorInnerStatus(), "");
        } else {
            //Step 4 : 订单内部流转记录的操作为“提交审核”
            baseOrderHistoryService.saveVendorInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.SUBMIT_VALIDATE, order.getVendorInnerStatus(), "");
        }

        //Step 5 : 统计采购商的数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatus, order.getBuyerInnerStatus());

        //Step 6 : 发送采购商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

        //Step 7: 如果是拼团订单，向营销服务发送拼团数据，等待拼团结果通知
        baseOrderService.notifyGroupOrder(order);

        //Step 8: 如果是代发货订单,向营销服务发送优惠券信息
        baseOrderService.sendCoupons(order);

        //Last step: 保存订单
        orderRepository.saveAndFlush(order);

        //维护送货计划
        deliveryPlanService.saveDeliveryPlanProduct(order);

        return Wrapper.success();
    }

    /**
     * “待新增订单” - 批量提交
     *
     * @param headers  Http头部信息
     * @param orderIds 接口参数
     * @return 删除结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> batchSubmitOrder(HttpHeaders headers, List<OrderIdVO> orderIds) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderDO> orders = orderRepository.findAllById(orderIds.stream().map(OrderIdVO::getOrderId).distinct().collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(orders) || orderIds.size() != orders.size() || orders.stream().anyMatch(order -> !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 0: 查询供应商业务员用户Id
        List<OrderMemberDTO> members = orders.stream().map(order -> new OrderMemberDTO(order.getBuyerMemberId(), order.getBuyerRoleId(), order.getVendorMemberId(), order.getVendorRoleId())).distinct().collect(Collectors.toList());
        Wrapper<List<OrderSalesDTO>> salesResult = baseOrderAuthService.findVendorSales(members);
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        //Step 1: 记录扣减库存成功的订单，在其他订单扣减库存失败，或工作流任务失败时，返还库存
        List<OrderDO> deduceSucessList = new ArrayList<>();

        //Step 2 : 循环执行提交
        for (OrderDO order : orders) {
            Wrapper<Void> deduceResult = baseOrderService.deduceInventory(order);
            if(deduceResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                deduceSucessList.forEach(deduceOrder -> baseOrderService.resumeInventory(deduceOrder));
                return Wrapper.fail(deduceResult.getCode(), deduceResult.getMessage());
            }

            deduceSucessList.add(order);

            int lastBuyerInnerStatus = order.getBuyerInnerStatus();
            Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                deduceSucessList.forEach(deduceOrder -> baseOrderService.resumeInventory(deduceOrder));
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            //Step 3: 以外部状态“待提交”作判断，订单是否已经提交给供应商
            //        如果外部状态为“待提交”，表示订单处于采购商审核过程中，否则表示订单已经提交给了“供应商”
            if(baseOrderService.hasSubmittedToVendor(order)) {
                //Step 3-1: 订单提交时间与供应商用户Id
                order.setSubmitTime(LocalDateTime.now());
                order.setVendorUserId(salesResult.getData().stream().filter(s -> s.getBuyerMemberId().equals(order.getBuyerMemberId()) && s.getBuyerRoleId().equals(order.getBuyerRoleId()) && s.getVendorMemberId().equals(order.getVendorMemberId()) && s.getVendorRoleId().equals(order.getVendorRoleId())).map(OrderSalesDTO::getVendorUserId).findFirst().orElse(null));

                //Step 3-2: 同步Srm订单数据至合同服务
                baseOrderService.sendSrmOrder(order);

                //Step 3-3 : 订单外部流转记录
                baseOrderHistoryService.saveVendorOrderOuterHistory(order.getId(), order.getOrderNo(), order.getVendorMemberId(), order.getVendorRoleId(), order.getVendorMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

                //Step 3-4 : 通知报表服务统计采购、供应双方的数据
                baseOrderService.reportVendorOrderAmount(order);

                //Step 3-5 : 统计供应商的数据
                baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

                //Step 3-6 : 发送供应商实时消息
                baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

                //Step 3-7 ： 供应商交易流程规则配置中的自动取消
                baseOrderScheduleService.scheduleOrderCancel(order.getId(), order.getTask() == null ? BigDecimal.ZERO : order.getTask().getExpireHours());

                //Step 4 : 订单内部流转记录的操作为“提交”
                baseOrderHistoryService.saveVendorInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.SUBMIT, order.getVendorInnerStatus(), "");
            } else {
                //Step 4 : 订单内部流转记录的操作为“提交审核”
                baseOrderHistoryService.saveVendorInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.SUBMIT_VALIDATE, order.getVendorInnerStatus(), "");
            }

            //Step 5 : 统计采购商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatus, order.getBuyerInnerStatus());

            //Step 6 : 发送采购商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

            //Step 7: 如果是拼团订单，向营销服务发送拼团数据，等待拼团结果通知
            baseOrderService.notifyGroupOrder(order);

            //Step 8: 如果是代发货订单,向营销服务发送优惠券信息
            baseOrderService.sendCoupons(order);
        }

        //Last step: 保存订单
        orderRepository.saveAll(orders);

        return Wrapper.success();
    }

    /**
     * “新增现货采购订单” - 分页查询现货采购订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BuyerToCreateQueryVO>> pagePurchaseOrders(HttpHeaders headers, BuyerOrderCreatePageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);

        Page<OrderDO> pageList = baseOrderService.pageCreatedOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), Stream.of(OrderTypeEnum.SPOT_PURCHASING, OrderTypeEnum.CHANNEL_STRAIGHT_MINING, OrderTypeEnum.CHANNEL_SPOT).collect(Collectors.toList()), pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerToCreateQueryVO queryVO = new BuyerToCreateQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setVendorMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setQuoteNo(order.getQuoteNo());
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            queryVO.setShowUpdate(order.getSeparateType().equals(OrderSeparateTypeEnum.DEFAULT.getCode()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “新增现货采购订单” - 根据商城类型查询订单类型和订单模式
     *
     * @param headers    Http头部信息
     * @param shopTypeVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<OrderModeVO> findPurchaseOrderTypes(HttpHeaders headers, PurchaseOrderShopTypeVO shopTypeVO) {
        switch (ShopTypeEnum.parseCode(shopTypeVO.getShopType())) {
            case ENTERPRISE:
                return Wrapper.success(new OrderModeVO(OrderModeEnum.BUYER));
            case CHANNEL:
                return Wrapper.success(new OrderModeVO(OrderModeEnum.CHANNEL_DIRECT_BUY));
            case CHANNEL_SELF:
                return Wrapper.success(new OrderModeVO(OrderModeEnum.CHANNEL_STOCK_BUY));
            default:
                return Wrapper.success(new OrderModeVO());
        }
    }

    /**
     * “新增现货采购订单” - 创建现货采购订单
     *
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 新增结果
     */
    @Override
    public Wrapper<Void> createPurchaseOrder(HttpHeaders headers, BuyerPurchaseOrderVO orderVO) {
        return orderCreationService.createPurchaseOrder(headers, orderVO);
    }

    /**
     * “新增现货采购订单” - 修改现货采购订单
     *
     * @param headers  Http头部信息
     * @param updateVO 接口参数
     * @return 新增结果
     */
    @Override
    public Wrapper<Void> updatePurchaseOrder(HttpHeaders headers, BuyerPurchaseOrderUpdateVO updateVO) {
        return orderCreationService.updatePurchaseOrder(headers, updateVO);
    }

    /**
     * 请购单订单 - 新增订单
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 新增结果
     */
    @Override
    public Wrapper<Void> createRequisitionOrder(HttpHeaders headers, RequisitionOrderCreateVO orderVO){
        return orderCreationService.createRequisitionOrder(headers, orderVO);
    }

    /**
     * 请购单订单 - 修改订单
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> updateRequisitionOrder(HttpHeaders headers, RequisitionOrderUpdateVO orderVO){
        return orderCreationService.updateRequisitionOrder(headers, orderVO);
    }

    /**
     * 新增请购单订单 - 分页查询
     * @param headers Http头部信息
     * @param pageVO 接口参数
     * @return 新增结果
     */
    @Override
    public Wrapper<PageData<BuyerToCreateQueryVO>> createRequisitionPage(HttpHeaders headers, BuyerOrderCreatePageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderTypeEnum> orderTypes = Collections.singletonList(OrderTypeEnum.REQUISITION_TO_PURCHASE);

        Page<OrderDO> pageList = baseOrderService.pageCreatedOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), orderTypes, pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerToCreateQueryVO queryVO = new BuyerToCreateQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setVendorMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setQuoteNo(order.getQuoteNo());
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            queryVO.setShowUpdate(BuyerInnerStatusEnum.BUYER_GRADE_ONE_NOT_PASSED.getCode().equals(order.getOuterStatus()) || BuyerInnerStatusEnum.BUYER_GRADE_TWO_NOT_PASSED.getCode().equals(order.getOuterStatus()) || BuyerInnerStatusEnum.BUYER_TO_SUBMIT_VALIDATE.getCode().equals(order.getOuterStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * （订单审核各个页面）获取前端页面下拉框列表
     *
     * @param headers Http头部信息
     * @return 查询结果
     */
    @Override
    public Wrapper<ValidatePageItemVO> getValidatePageItems(HttpHeaders headers) {
        baseCacheService.needLoginFromBusinessPlatform(headers);
        ValidatePageItemVO itemVO = new ValidatePageItemVO();
        itemVO.setOrderTypes(baseOrderService.listOrderTypes());
        return Wrapper.success(itemVO);
    }

    /**
     * “待审核订单（一级）” - 分页查询订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<OrderPageQueryVO>> pageToValidateGradeOneOrders(HttpHeaders headers, OrderPageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        Page<OrderDO> pageList = baseOrderService.pageBuyerOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), BuyerInnerStatusEnum.BUYER_VALIDATE_GRADE_ONE.getCode(), null, pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            OrderPageQueryVO queryVO = new OrderPageQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待审核订单（一级）” - 查询订单详情
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerOrderDetailVO> getToValidateGradeOneOrderDetails(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        return baseOrderService.getBuyerOrderDetail(order, BuyerInnerStatusEnum.BUYER_VALIDATE_GRADE_ONE);
    }

    /**
     * “待审核订单（一级）” - 审核
     *
     * @param headers Http头部信息
     * @param agreeVO 接口参数
     * @return 审核结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> validateOrderGradeOne(HttpHeaders headers, OrderAgreeVO agreeVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return validateOrderGradeOne(loginUser, agreeVO);
    }

    /**
     * “待审核订单（一级）” - 审核
     *
     * @param loginUser 登录用户
     * @param agreeVO   接口参数
     * @return 审核结果
     */
    @Override
    public Wrapper<Void> validateOrderGradeOne(UserLoginCacheDTO loginUser, OrderAgreeVO agreeVO) {
        OrderDO order = orderRepository.findById(agreeVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_VALIDATE_GRADE_ONE.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1: 参数判断
        if(agreeVO.getAgree().equals(OrderServiceContants.DISAGREE) && !StringUtils.hasLength(agreeVO.getReason())) {
            return Wrapper.fail(ResponseCode.ORDER_VALIDATE_REASON_CAN_NOT_BE_EMPTY);
        }

        //Step 2: 执行工作流任务（修改订单状态、记录内外流转记录）
        int lastBuyerInnerStatus = order.getBuyerInnerStatus();
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order, agreeVO.getAgree());
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        orderRepository.saveAndFlush(order);

        //Step 2 : 订单内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.VALIDATE_GRADE_ONE, order.getBuyerInnerStatus(), StringUtils.hasLength(agreeVO.getReason()) ? agreeVO.getReason() : "");

        //Step 3 : 发送采购商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

        //Step 4: 向报表服务发送统计数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatus, order.getBuyerInnerStatus());
        return Wrapper.success();
    }

    /**
     * “待审核订单（一级）” - 批量审核
     *
     * @param headers  Http头部信息
     * @param orderIds 接口参数
     * @return 审核结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> batchValidateOrdersGradeOne(HttpHeaders headers, List<OrderIdVO> orderIds) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderDO> orders = orderRepository.findAllById(orderIds.stream().map(OrderIdVO::getOrderId).distinct().collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(orders) || orderIds.size() != orders.size() || orders.stream().anyMatch(order -> !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_VALIDATE_GRADE_ONE.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1: 记录订单的上一次内部状态，用于向报表服务发送采购商消息
        Map<Long, Integer> lastBuyerInnerStatusMap = orders.stream().collect(Collectors.toMap(OrderDO::getId, OrderDO::getBuyerInnerStatus));

        //Step 2 : 执行工作流任务
        for (OrderDO order : orders) {
            Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order, OrderServiceContants.AGREE);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }
        }
        orderRepository.saveAll(orders);

        //Step 3 : 订单内部流转记录、消息服务发送
        orders.forEach(order -> {
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.VALIDATE_GRADE_ONE, order.getBuyerInnerStatus(), "");
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatusMap.getOrDefault(order.getId(), 0), order.getBuyerInnerStatus());
        });

        return Wrapper.success();
    }

    /**
     * “待审核订单（二级）” - 分页查询订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<OrderPageQueryVO>> pageToValidateGradeTwoOrders(HttpHeaders headers, OrderPageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        Page<OrderDO> pageList = baseOrderService.pageBuyerOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), BuyerInnerStatusEnum.BUYER_VALIDATE_GRADE_TWO.getCode(), null, pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            OrderPageQueryVO queryVO = new OrderPageQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待审核订单（二级）” - 查询订单详情
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerOrderDetailVO> getToValidateGradeTwoOrderDetails(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        return baseOrderService.getBuyerOrderDetail(order, BuyerInnerStatusEnum.BUYER_VALIDATE_GRADE_TWO);
    }

    /**
     * “待审核订单（二级）” - 审核
     *
     * @param headers Http头部信息
     * @param agreeVO 接口参数
     * @return 审核结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> validateOrderGradeTwo(HttpHeaders headers, OrderAgreeVO agreeVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return validateOrderGradeTwo(loginUser, agreeVO);
    }

    /**
     * “待审核订单（二级）” - 审核
     *
     * @param loginUser 登录用户
     * @param agreeVO   接口参数
     * @return 审核结果
     */
    @Override
    public Wrapper<Void> validateOrderGradeTwo(UserLoginCacheDTO loginUser, OrderAgreeVO agreeVO) {
        OrderDO order = orderRepository.findById(agreeVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_VALIDATE_GRADE_TWO.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1: 参数判断
        if(agreeVO.getAgree().equals(OrderServiceContants.DISAGREE) && !StringUtils.hasLength(agreeVO.getReason())) {
            return Wrapper.fail(ResponseCode.ORDER_VALIDATE_REASON_CAN_NOT_BE_EMPTY);
        }

        //Step 2: 执行工作流任务（修改订单状态、记录内外流转记录）
        int lastBuyerInnerStatus = order.getBuyerInnerStatus();
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order, agreeVO.getAgree());
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        orderRepository.saveAndFlush(order);

        //Step 2 : 订单内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.VALIDATE_GRADE_TWO, order.getBuyerInnerStatus(), StringUtils.hasLength(agreeVO.getReason()) ? agreeVO.getReason() : "");

        //Step 3 : 发送采购商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

        //Step 4: 向报表服务发送统计数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatus, order.getBuyerInnerStatus());

        return Wrapper.success();
    }

    /**
     * “待审核订单（二级）” - 批量审核
     *
     * @param headers  Http头部信息
     * @param orderIds 接口参数
     * @return 审核结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> batchValidateOrdersGradeTwo(HttpHeaders headers, List<OrderIdVO> orderIds) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderDO> orders = orderRepository.findAllById(orderIds.stream().map(OrderIdVO::getOrderId).distinct().collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(orders) || orderIds.size() != orders.size() || orders.stream().anyMatch(order -> !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_VALIDATE_GRADE_TWO.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1: 记录订单的上一次内部状态，用于向报表服务发送采购商消息
        Map<Long, Integer> lastBuyerInnerStatusMap = orders.stream().collect(Collectors.toMap(OrderDO::getId, OrderDO::getBuyerInnerStatus));

        //Step 2 : 执行工作流任务
        for (OrderDO order : orders) {
            Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order, OrderServiceContants.AGREE);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }
        }
        orderRepository.saveAll(orders);

        //Step 3 : 订单内部流转记录、消息服务发送
        orders.forEach(order -> {
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.VALIDATE_GRADE_TWO, order.getBuyerInnerStatus(), "");
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatusMap.getOrDefault(order.getId(), 0), order.getBuyerInnerStatus());
        });

        return Wrapper.success();
    }

    /**
     * “待提交订单” - 分页查询订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<OrderPageQueryVO>> pageToSubmitOrders(HttpHeaders headers, OrderPageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        Page<OrderDO> pageList = baseOrderService.pageBuyerOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), BuyerInnerStatusEnum.BUYER_TO_SUBMIT.getCode(), null, pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            OrderPageQueryVO queryVO = new OrderPageQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待提交订单” - 查询订单详情
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerOrderDetailVO> getToSubmitOrderDetails(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        return baseOrderService.getBuyerOrderDetail(order, BuyerInnerStatusEnum.BUYER_TO_SUBMIT);
    }

    /**
     * “待提交订单” - 提交
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 审核结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> submitValidateOrder(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return submitValidateOrder(loginUser, idVO);
    }

    /**
     * “待提交订单” - 提交
     *
     * @param loginUser 登录用户
     * @param idVO      接口参数
     * @return 审核结果
     */
    @Override
    public Wrapper<Void> submitValidateOrder(UserLoginCacheDTO loginUser, OrderIdVO idVO) {
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1 : 执行工作流任务（修改订单状态、记录内外流转记录）
        int lastBuyerInnerStatus = order.getBuyerInnerStatus();
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order);
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        //Step 2 : 提交之后有可能是支付环节，判断是否跳过支付环节
        Wrapper<OrderPaymentBO> jumpResult = baseOrderPaymentService.jumpOverOrderPaySerialTasks(order);
        if(jumpResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(jumpResult.getCode(), jumpResult.getMessage());
        }

        //Step 3: 查询供应商业务员Id
        Wrapper<Long> salesResult = baseOrderAuthService.findVendorSalesUserId(order.getBuyerMemberId(), order.getBuyerRoleId(), order.getVendorMemberId(), order.getVendorRoleId());
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        //Step 4: 以外部状态“待提交”作判断，订单是否已经提交给供应商
        //        如果外部状态为“待提交”，表示订单处于采购商审核过程中，否则表示订单已经提交给了“供应商”
        if(baseOrderService.hasSubmittedToVendor(order)) {
            //Step 4-1: 订单提交时间与供应商用户Id
            order.setSubmitTime(LocalDateTime.now());
            order.setVendorUserId(salesResult.getData());

            //Step 4-2: 同步Srm订单数据至合同服务
            baseOrderService.sendSrmOrder(order);

            //Step 4-3 : 订单外部流转记录
            baseOrderHistoryService.saveVendorOrderOuterHistory(order.getId(), order.getOrderNo(), order.getVendorMemberId(), order.getVendorRoleId(), order.getVendorMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            //Step 4-4 : 通知报表服务统计采购、供应双方的数据
            baseOrderService.reportVendorOrderAmount(order);

            //Step 4-5 : 统计供应商的数据
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

            //Step 4-6 : 发送供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

            //Step 4-7 ： 供应商交易流程规则配置中的自动取消
            baseOrderScheduleService.scheduleOrderCancel(order.getId(), order.getTask() == null ? BigDecimal.ZERO : order.getTask().getExpireHours());
        }

        //Step 5 : 订单内部流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.SUBMIT, order.getBuyerInnerStatus(), "");

        //Step 6 : 统计采购商的数据
        baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatus, order.getBuyerInnerStatus());

        //Step 7 : 发送采购商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

        //Step 8: 如果是拼团订单，向营销服务发送拼团数据，等待拼团结果通知
        baseOrderService.notifyGroupOrder(order);

        //Step 9: 如果是代发货订单,向营销服务发送优惠券信息
        baseOrderService.sendCoupons(order);

        //Step Final: 保存订单
        orderRepository.saveAndFlush(order);

        return Wrapper.success();
    }

    /**
     * “待提交订单” - 批量提交
     *
     * @param headers  Http头部信息
     * @param orderIds 接口参数
     * @return 审核结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> batchSubmitValidateOrders(HttpHeaders headers, List<OrderIdVO> orderIds) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        List<OrderDO> orders = orderRepository.findAllById(orderIds.stream().map(OrderIdVO::getOrderId).distinct().collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(orders) || orderIds.size() != orders.size() || orders.stream().anyMatch(order -> !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_SUBMIT.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 0: 查询供应商业务员用户Id
        List<OrderMemberDTO> members = orders.stream().map(order -> new OrderMemberDTO(order.getBuyerMemberId(), order.getBuyerRoleId(), order.getVendorMemberId(), order.getVendorRoleId())).distinct().collect(Collectors.toList());
        Wrapper<List<OrderSalesDTO>> salesResult = baseOrderAuthService.findVendorSales(members);
        if(salesResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(salesResult.getCode(), salesResult.getMessage());
        }

        //Step 1: 批量记录上一次的采购商内部状态，用于发送报表统计数据
        Map<Long, Integer> lastBuyerInnerStatusMap = orders.stream().collect(Collectors.toMap(OrderDO::getId, OrderDO::getBuyerInnerStatus));

        //Step 2 : 循环执行提交
        for (OrderDO order : orders) {
            Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order);
            if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            //Step 3 : 提交之后有可能是支付环节，判断是否跳过支付环节
            Wrapper<OrderPaymentBO> jumpResult = baseOrderPaymentService.jumpOverOrderPaySerialTasks(order);
            if(jumpResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(jumpResult.getCode(), jumpResult.getMessage());
            }

            //Step 4: 以外部状态“待提交”作判断，订单是否已经提交给供应商
            //        如果外部状态为“待提交”，表示订单处于采购商审核过程中，否则表示订单已经提交给了“供应商”
            if(baseOrderService.hasSubmittedToVendor(order)) {
                //Step 4-1: 订单提交时间与供应商用户Id
                order.setSubmitTime(LocalDateTime.now());
                order.setVendorUserId(salesResult.getData().stream().filter(s -> s.getBuyerMemberId().equals(order.getBuyerMemberId()) && s.getBuyerRoleId().equals(order.getBuyerRoleId()) && s.getVendorMemberId().equals(order.getVendorMemberId()) && s.getVendorRoleId().equals(order.getVendorRoleId())).map(OrderSalesDTO::getVendorUserId).findFirst().orElse(null));

                //Step 4-2: 同步Srm订单数据至合同服务
                baseOrderService.sendSrmOrder(order);

                //Step 4-3 : 订单外部流转记录
                baseOrderHistoryService.saveVendorOrderOuterHistory(order.getId(), order.getOrderNo(), order.getVendorMemberId(), order.getVendorRoleId(), order.getVendorMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.SUBMIT, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

                //Step 4-4 : 通知报表服务统计采购、供应双方的数据
                baseOrderService.reportVendorOrderAmount(order);

                //Step 4-5 : 统计供应商的数据
                baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), null, order.getVendorInnerStatus());

                //Step 4-6 : 发送供应商实时消息
                baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

                //Step 4-7： 供应商交易流程规则配置中的自动取消
                baseOrderScheduleService.scheduleOrderCancel(order.getId(), order.getTask() == null ? BigDecimal.ZERO : order.getTask().getExpireHours());
            }

            //Step 5 : 订单内部流转记录
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.SUBMIT, order.getBuyerInnerStatus(), "");

            //Step 6 : 统计采购商的数据
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatusMap.getOrDefault(order.getId(), 0), order.getBuyerInnerStatus());

            //Step 7 : 发送采购商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());

            //Step 8: 如果是拼团订单，向营销服务发送拼团数据，等待拼团结果通知
            baseOrderService.notifyGroupOrder(order);

            //Step 9: 如果是代发货订单,向营销服务发送优惠券信息
            baseOrderService.sendCoupons(order);
        }

        //Last step : 保存订单
        orderRepository.saveAll(orders);

        return Wrapper.success();
    }

    /**
     * “待支付订单” - 查询订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BuyerToPayQueryVO>> pageToPayOrders(HttpHeaders headers, OrderValidatePageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);

        Pageable pageable = PageRequest.of(pageVO.getCurrent() -1, pageVO.getPageSize(), Sort.by("id").descending());
        Specification<OrderDO> specification = (Specification<OrderDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("buyerMemberId").as(Long.class), loginUser.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("buyerRoleId").as(Long.class), loginUser.getMemberRoleId()));

            //订单编号
            if(StringUtils.hasLength(pageVO.getOrderNo())) {
                list.add(criteriaBuilder.like(root.get("orderNo").as(String.class), "%" + pageVO.getOrderNo().trim() + "%"));
            }

            //订单摘要
            if(StringUtils.hasLength(pageVO.getDigest())) {
                list.add(criteriaBuilder.like(root.get("digest").as(String.class), "%" + pageVO.getDigest().trim() + "%"));
            }

            //供应会员名称
            if(StringUtils.hasLength(pageVO.getMemberName())) {
                list.add(criteriaBuilder.like(root.get("vendorMemberName").as(String.class), "%" + pageVO.getMemberName().trim() + "%"));
            }

            //订单起始时间
            if (StringUtils.hasLength(pageVO.getStartDate())) {
                list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), LocalDateTime.parse(pageVO.getStartDate().concat(" 00:00:00"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
            }

            //订单结束时间
            if (StringUtils.hasLength(pageVO.getEndDate())) {
                list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(LocalDateTime.class), LocalDateTime.parse(pageVO.getEndDate().concat(" 23:59:59"), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));
            }

            //订单类型
            if(NumberUtil.notNullOrZero(pageVO.getOrderType())) {
                list.add(criteriaBuilder.equal(root.get("orderType").as(Integer.class), pageVO.getOrderType()));
            }

            //“待支付订单” 的 状态：“未支付”、“支付中”、 “支付失败”、“支付成功，但被供应商确认未到账”
            list.add(criteriaBuilder.or(
                    criteriaBuilder.equal(root.get("buyerInnerStatus").as(Integer.class), BuyerInnerStatusEnum.BUYER_TO_PAY.getCode()),
                    criteriaBuilder.equal(root.get("buyerInnerStatus").as(Integer.class), BuyerInnerStatusEnum.BUYER_PAYING.getCode()),
                    criteriaBuilder.equal(root.get("buyerInnerStatus").as(Integer.class), BuyerInnerStatusEnum.BUYER_PAY_FAIL.getCode()),
                    criteriaBuilder.and(criteriaBuilder.equal(root.get("buyerInnerStatus").as(Integer.class), BuyerInnerStatusEnum.BUYER_PAY_SUCCESS.getCode()),
                            criteriaBuilder.equal(root.get("outerStatus").as(Integer.class), OrderOuterStatusEnum.PAYMENT_NOT_ACCOMPLISH.getCode())
                            )
            ));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<OrderDO> pageList = orderRepository.findAll(specification, pageable);
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerToPayQueryVO queryVO = new BuyerToPayQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            //显示最小的未支付批次：（内部状态为“未支付”或“支付失败”） 或 （“支付成功”且外部状态为“确认未到账”）
            queryVO.setBatchNo(CollectionUtils.isEmpty(order.getPayments()) ? 0 : order.getPayments().stream().filter(payment -> payment.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_PAY.getCode()) || payment.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_PAY_FAIL.getCode()) || (payment.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_PAY_SUCCESS.getCode()) && payment.getOuterStatus().equals(OrderOuterStatusEnum.PAYMENT_NOT_ACCOMPLISH.getCode()))).map(OrderPaymentDO::getBatchNo).min(Comparator.comparingInt(Integer::intValue)).orElse(0));
            queryVO.setBatchCount(CollectionUtils.isEmpty(order.getPayments()) ? 0 : order.getPayments().size());
            queryVO.setPaidAmount(NumberUtil.formatAmount(order.getPaidAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待支付订单” - 查询订单详情
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerOrderDetailVO> getToPayOrderDetails(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        if(!(order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_PAY.getCode()) || order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_PAYING.getCode()) || order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_PAY_FAIL.getCode()) || (order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_PAY_SUCCESS.getCode()) && order.getOuterStatus().equals(OrderOuterStatusEnum.PAYMENT_NOT_ACCOMPLISH.getCode())))) {
            return Wrapper.fail(ResponseCode.ORDER_STATUS_IS_NOT_MATCHED);
        }

        return baseOrderService.getBuyerOrderDetail(order);
    }

    /**
     * “待支付订单” - 订单详情 - 查询支付方式与支付渠道列表
     *
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<OrderPayTypeDetailVO>> getToPayOrderPayTypes(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return getToPayOrderPayTypes(loginUser, idVO);
    }

    /**
     * “待支付订单” - 订单详情 - 查询支付方式与支付渠道列表
     *
     * @param loginUser 登录用户
     * @param idVO      接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<OrderPayTypeDetailVO>> getToPayOrderPayTypes(UserLoginCacheDTO loginUser, OrderIdVO idVO) {
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        return baseOrderProcessService.findMemberPayment(loginUser.getMemberId(), loginUser.getMemberRoleId(), order.getVendorMemberId(), order.getVendorRoleId());
    }

    /**
     * “待支付订单” - 订单支付
     *
     * @param headers HttpHeader信息
     * @param payVO   接口参数
     * @return 支付链接（在线支付）
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<PayResultDetailVO> orderPay(HttpHeaders headers, BuyerOrderPayVO payVO) {
        BuyerMergePayVO mergePayVO = new BuyerMergePayVO();
        mergePayVO.setOrderIds(Collections.singletonList(payVO.getOrderId()));
        mergePayVO.setFundMode(payVO.getFundMode());
        mergePayVO.setPayType(payVO.getPayType());
        mergePayVO.setPayChannel(payVO.getPayChannel());
        mergePayVO.setBatchNo(payVO.getBatchNo());
        mergePayVO.setVouchers(payVO.getVouchers());
        mergePayVO.setPayPassword(payVO.getPayPassword());
        mergePayVO.setWeChatCode(payVO.getWeChatCode());
        mergePayVO.setReturnUrl(payVO.getReturnUrl());
        return orderPay(headers, mergePayVO);
    }

    /**
     * “待支付订单” - 订单支付
     *
     * @param headers HttpHeader信息
     * @param payVO   接口参数
     * @return 支付链接（在线支付）
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<PayResultDetailVO> orderPay(HttpHeaders headers, BuyerMergePayVO payVO) {
        UserLoginCacheDTO loginUser = baseCacheService.checkUserFromCache(headers);
        //建行B2B支付暂不支持App、小程序支付
        if(loginUser.getLoginSource().equals(UserLoginSourceEnum.BUSINESS_MOBILE.getCode()) && payVO.getPayChannel().equals(OrderPayChannelEnum.CCB_B2B.getCode())) {
            return Wrapper.fail(ResponseCode.ORDER_CBC_B2B_PAY_DOES_NOT_SUPPORT_APP_PAY);
        }

        List<OrderDO> orders = orderRepository.findAllById(payVO.getOrderIds());
        if(CollectionUtils.isEmpty(orders) || orders.stream().anyMatch(order -> !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId()))) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //不需要支付时，直接返回
        if(payVO.getPayType().equals(OrderPayTypeEnum.DOES_NOT_NEED.getCode()) || payVO.getPayChannel().equals(OrderPayChannelEnum.DOES_NOT_NEED.getCode())) {
            return Wrapper.success(new PayResultDetailVO());
        }

        //Step 1: 记录采购、供应的上一次内部状态，用于发送报表统计数据
        List<OrderStatusDTO> lastStatus = orders.stream().map(order -> new OrderStatusDTO(order.getId(), order.getBuyerInnerStatus(), order.getVendorInnerStatus())).collect(Collectors.toList());

        //Step 2: 支付
        Wrapper<OrderPayResultBO> payResult = baseOrderPaymentService.buyerPay(loginUser, orders, payVO.getFundMode(), payVO.getBatchNo(), payVO.getPayType(), payVO.getPayChannel(), payVO.getVouchers(), payVO.getPayPassword(), payVO.getWeChatCode(), payVO.getReturnUrl());
        if(payResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(payResult.getCode(), payResult.getMessage());
        }

        //如果是建行支付，将订单状态设置为“支付中”状态
        if(payVO.getPayChannel().equals(OrderPayChannelEnum.CCB_B2B.getCode())) {
            orders.forEach(order -> order.setBuyerInnerStatus(BuyerInnerStatusEnum.BUYER_PAYING.getCode()));
        }

        orders.stream().filter(orderDO -> orderDO.getOuterStatus().equals(OrderOuterStatusEnum.ACCOMPLISHED.getCode())).forEach(orderDO -> orderDO.setFinishTime(LocalDateTime.now()));
        orderRepository.saveAll(orders);

        //Step 4-1 : 订单内、外流转记录
        orders.forEach(order -> {
            baseOrderHistoryService.saveBuyerInnerHistory(loginUser.getMemberId(), loginUser.getMemberRoleId(), loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.PAY, order.getBuyerInnerStatus(), "");
            baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), loginUser.getMemberRoleName(), OrderOperationEnum.PAY, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            //Step 4-2: 向报表服务发送订单统计数据
            OrderStatusDTO status = lastStatus.stream().filter(s -> s.getOrderId().equals(order.getId())).findFirst().orElse(null);
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), status == null ? 0 : status.getLastBuyerInnerStatus(), order.getBuyerInnerStatus());

            //Step 4-3: 查询线下支付订单供应商的资金归结模式
            Integer fundMode = basePlatformPaymentTypeService.getFundModeByMemberIdAndRoleId(order.getVendorMemberId(), order.getVendorRoleId());

            //如果是线下支付 && 资金归结模式为会员直接到账的话   流程执行之前的(上一次的供应商内部状态)不能减少统计的操作
            if(OrderPayTypeEnum.OFFLINE_PAYMENT.getCode().equals(payVO.getPayType()) && FundModeEnum.DIRECT_TO_ACCOUNT.getCode().equals(fundMode)){
                baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), 0, order.getVendorInnerStatus());
            }else {
                baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), status == null ? 0 : status.getLastVendorInnerStatus(), order.getVendorInnerStatus());
            }

            //Step 4-3: 向消息服务发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());

            //Step 4-5: 如果是拼团订单，向营销服务发送拼团数据，等待拼团结果通知
            baseOrderService.notifyGroupOrder(order);

            //Step 4-5-1: 如果是代发货订单,向营销服务发送优惠券信息
            baseOrderService.sendCoupons(order);

            //Step 4-4 : 订单完成后的操作
            baseOrderService.operateAfterOrderAccomplished(order);
        });

        //Step 5: 支付后，将订单的“平台优惠券”信息，同步给结算服务
        baseOrderService.notifyPlatformCoupons(orders);

        return Wrapper.success(new PayResultDetailVO(payResult.getData().getCodeUrl(), payResult.getData().getTradeNo()));
    }

    /**
     * “待支付订单” - 查询支付结果
     *
     * @param headers  HttpHeader信息
     * @param resultVO 接口参数
     * @return 支付结果
     */
    @Override
    public Wrapper<BuyerPayResultDetailVO> findPayResult(HttpHeaders headers, BuyerPayResultVO resultVO) {
        return baseOrderPaymentService.findPayResult(resultVO.getTradeNo());
    }

    /**
     * 订单支付 - （线上支付）回调接口
     *
     * @param tradeNo    订单交易号
     * @param attach     透传参数
     * @param paySuccess 是否支付成功
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> orderPayCallback(String tradeNo, String attach, Boolean paySuccess) {
        //Step 1: 从缓存中读取支付用户信息
        PaymentCacheDTO paymentCache = baseCacheService.findOrderPayment(attach);
        if(paymentCache == null) {
            return Wrapper.fail(ResponseCode.ORDER_PAYMENT_CACHE_DOES_NOT_EXIST);
        }

        List<OrderDO> orders = orderRepository.findAllById(paymentCache.getPayments().stream().map(OrderPaymentDTO::getOrderId).collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(orders) || orders.size() != paymentCache.getPayments().size()) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1: 记录采购、供应的上一次内部状态，用于发送报表统计数据
        List<OrderStatusDTO> lastStatus = orders.stream().map(order -> new OrderStatusDTO(order.getId(), order.getBuyerInnerStatus(), order.getVendorInnerStatus())).collect(Collectors.toList());

        //Step 2: 修改支付记录状态，执行流程
        Wrapper<Void> callbackResult = baseOrderPaymentService.buyerPayCallback(orders, paymentCache, paySuccess);
        if (callbackResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(callbackResult.getCode(), callbackResult.getMessage());
        }
        orders.stream().filter(orderDO -> orderDO.getOuterStatus().equals(OrderOuterStatusEnum.ACCOMPLISHED.getCode())).forEach(orderDO -> orderDO.setFinishTime(LocalDateTime.now()));
        orderRepository.saveAll(orders);

        orders.forEach(order -> {
            String remark = paymentCache.getPayments().stream().filter(p -> p.getOrderId().equals(order.getId())).map(p -> "支付次数:".concat(String.valueOf(p.getBatchNo()))).findFirst().orElse("");
            if(paySuccess) {
                //Step 4-2-a : 订单内、外流转记录 ： 内部记录：支付成功；外部记录：一次支付成功，一次确认到账
                baseOrderHistoryService.saveBuyerInnerHistory(paymentCache.getMemberId(), paymentCache.getRoleId(), paymentCache.getUserName(), paymentCache.getOrganization(), paymentCache.getJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.PAY_SUCCESS, order.getBuyerInnerStatus(), remark);
                baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), OrderServiceContants.SYSTEM_NAME, OrderOperationEnum.CONFIRM_PAYMENT, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), remark);
            } else {
                //Step 4-2-b : 订单内部流转记录 ： 支付失败
                baseOrderHistoryService.saveBuyerInnerHistory(paymentCache.getMemberId(), paymentCache.getRoleId(), paymentCache.getUserName(), paymentCache.getOrganization(), paymentCache.getJobTitle(), order.getId(), order.getOrderNo(), OrderOperationEnum.PAY_FAILED, order.getBuyerInnerStatus(), remark);
            }

            //Step 4-3: 向报表服务发送订单统计数据
            OrderStatusDTO status = lastStatus.stream().filter(s -> s.getOrderId().equals(order.getId())).findFirst().orElse(null);
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), status == null ? 0 : status.getLastBuyerInnerStatus(), order.getBuyerInnerStatus());
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), status == null ? 0 : status.getLastVendorInnerStatus(), order.getVendorInnerStatus());

            //Step 4-4: 向消息服务发送采购商、供应商实时消息
            baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
            baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());

            //Step 4-5： 如果是拼团订单，通知营销服务
            baseOrderService.notifyGroupOrder(order);

            //Step 4-5-1: 如果是代发货订单,向营销服务发送优惠券信息
            baseOrderService.sendCoupons(order);

            //Step 4-6 : 订单完成后的操作
            baseOrderService.operateAfterOrderAccomplished(order);

            //订单确认时维护送货计划物料数据
            if(paySuccess) {
                deliveryPlanService.saveDeliveryPlanProduct(order);
            }

        });

        return Wrapper.success();
    }

    /**
     * “待发货订单” - 查询订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BuyerToDeliveryQueryVO>> pageToDeliveryOrders(HttpHeaders headers, OrderValidatePageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        Page<OrderDO> pageList = baseOrderService.pageBuyerOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), null, OrderOuterStatusEnum.TO_CONFIRM_DELIVERY.getCode(), pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerToDeliveryQueryVO queryVO = new BuyerToDeliveryQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            queryVO.setShopId(order.getShopId());
            queryVO.setShopEnvironment(order.getShopEnvironment());
            //是否显示“售后”：当前订单是参与了拼团活动的订单，且拼团状态为拼团失败，且订单的外部状态为“待确认发货
            queryVO.setShowAfterSales(baseOrderService.canAfterSaleOrder(order));
            //是否可以“邀请拼团”
            queryVO.setShowInvite(baseOrderService.canBuyerInviteGroup(order));
            queryVO.setGroupId(queryVO.getShowInvite() ? baseOrderPromotionService.findGroupOrderRecordId(order) : 0L);
            queryVO.setSkuId(queryVO.getShowInvite() ? order.getProducts().stream().map(OrderProductDO::getSkuId).findFirst().orElse(0L) : 0L);
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待发货订单” - 订单详情 - 邀请好友拼团 - 生成小程序码分享链接
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<String> createDeliveryMiniAppCode(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if (order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //获取小程序配置参数，param：二维码参数，page: 跳转页面路径 = order/mycommodityDetails 。小程序未发布增加这个参数会报错，暂时定义为空
        return baseOrderService.createMiniCode(order.getId().toString(), "");
    }

    /**
     * “待新增采购收货单” - 查询订单列表
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BuyerOrderReceiveQueryVO>> pageCreateReceiveOrders(HttpHeaders headers, BuyerOrderReceivePageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);

        Page<OrderDO> pageList = baseOrderService.pageBuyerOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), null, OrderOuterStatusEnum.TO_RECEIVE.getCode(), pageVO.getCurrent(), pageVO.getPageSize());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerOrderReceiveQueryVO queryVO = new BuyerOrderReceiveQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            //显示最后一次的发货批次，即发货记录的条数
            queryVO.setBatchNo(order.getDeliveries().size());
            queryVO.setReceiptNo("");
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待新增采购收货单” - 创建收货单
     * @param headers Http头部信息
     * @param orderVO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> createReceiveOrder(HttpHeaders headers, BuyerCreateReceiveVO orderVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);

        OrderDO order = orderRepository.findById(orderVO.getOrderId()).orElse(null);
        if (order == null || !order.getVendorMemberId().equals(loginUser.getMemberId()) || !order.getVendorRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //执行工作流任务（修改订单状态、记录内外流转记录）
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order);
        if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        SellDeliveryGoodsDO deliveryDO = new SellDeliveryGoodsDO();
        deliveryDO.setDigest(orderVO.getDigest());
        deliveryDO.setCreateTime(LocalDateTime.parse(orderVO.getOrderTime(), OrderServiceContants.DEFAULT_TIME_FORMATTER));
        deliveryDO.setInventoryName(orderVO.getInventoryName());
        deliveryDO.setInventoryRole(orderVO.getInventoryRole());
        deliveryDO.setOrderId(orderVO.getOrderId());
        deliveryDO.setOrderNo(order.getOrderNo());
        deliveryDO.setRemark(orderVO.getRemark());
        deliveryDO.setVendorMemberId(order.getVendorMemberId());
        deliveryDO.setVendorRoleId(order.getVendorRoleId());
        deliveryDO.setVendorMemberName(order.getVendorMemberName());
        //没有该字段，设置默认值
        deliveryDO.setBuyerMemberId(0L);
        deliveryDO.setBuyerRoleId(0L);
        deliveryDO.setBuyerMemberName("");
        //商品明细
        deliveryDO.setDetailList(orderVO.getDetailList().stream().map(detail -> {
            SellDeliveryGoodsDetailDO detailDO = new SellDeliveryGoodsDetailDO();
            detailDO.setProductId(detail.getProductId());
            detailDO.setName(detail.getName());
            detailDO.setCategory(detail.getCategory());
            detailDO.setBrand(detail.getBrand());
            detailDO.setUnit(detail.getUnit());
            detailDO.setOrderQuantity(detail.getOrderQuantity());
            detailDO.setPrice(detail.getPrice());
            detailDO.setDeliveryQuantity(detail.getDeliveryQuantity());
            detailDO.setAmount(detail.getAmount());
            detailDO.setWeight(detail.getWeight());
            detailDO.setDeliveryGoods(deliveryDO);
            return detailDO;
        }).collect(Collectors.toSet()));

        //保存发货单
        sellDeliveryGoodsRepository.save(deliveryDO);

        //保存订单，修改订单状态
        orderRepository.saveAndFlush(order);

        return Wrapper.success();
    }

    /**
     * “待新增采购收货单” - 查看详情
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerReceiveDetailVO> getReceiveDetail(HttpHeaders headers, OrderIdVO idVO) {
        baseCacheService.needLoginFromBusinessPlatform(headers);

        SellDeliveryGoodsDO delivery = sellDeliveryGoodsRepository.findFirstByOrderId(idVO.getOrderId());
        if (delivery == null) {
            return Wrapper.fail(ResponseCode.ORDER_SELL_DELIVERY_BILL_DOES_NOT_EXIST);
        }
        BuyerReceiveDetailVO detailVO = new BuyerReceiveDetailVO();

        detailVO.setInventoryName(delivery.getInventoryName());
        detailVO.setInventoryRole(delivery.getInventoryRole());
        detailVO.setDigest(delivery.getDigest());
        detailVO.setCreateTime(delivery.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
        detailVO.setRemark(delivery.getRemark());
        detailVO.setOrderNo(delivery.getOrderNo());
        detailVO.setOrderId(idVO.getOrderId());
        detailVO.setVendorMemberId(delivery.getVendorMemberId());
        detailVO.setVendorRoleId(delivery.getVendorRoleId());
        detailVO.setVendorMemberName(delivery.getVendorMemberName());
        //收货单商品明细
        detailVO.setDetailList(delivery.getDetailList().stream().map(detail -> {
            SellDeliveryGoodsDetailVO goodsDetailVO = new SellDeliveryGoodsDetailVO();
            goodsDetailVO.setId(detail.getId());
            goodsDetailVO.setProductId(detail.getProductId());
            goodsDetailVO.setName(detail.getName());
            goodsDetailVO.setCategory(detail.getCategory());
            goodsDetailVO.setBrand(detail.getBrand());
            goodsDetailVO.setUnit(detail.getUnit());
            goodsDetailVO.setOrderQuantity(detail.getOrderQuantity());
            goodsDetailVO.setPrice(detail.getPrice());
            goodsDetailVO.setDeliveryQuantity(detail.getDeliveryQuantity());
            goodsDetailVO.setAmount(detail.getAmount());
            goodsDetailVO.setWeight(detail.getWeight());
            return goodsDetailVO;
        }).collect(Collectors.toList()));

        //订单发货人信息
        detailVO.setConsignee(baseOrderConsigneeService.getOrderConsignee(idVO.getOrderId()));

        return Wrapper.success();
    }

    /**
     * “待新增采购收货单” - 提交审核
     * @param headers Http头部信息
     * @param idVO    接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<Void> validateToReceiveOrder(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if (order == null || !order.getBuyerInnerStatus().equals(BuyerInnerStatusEnum.BUYER_TO_VALIDATE_DEPOT.getCode()) || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //执行工作流任务（修改订单状态、记录内外流转记录）
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order);
        if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        orderRepository.saveAndFlush(order);

        return Wrapper.success();
    }

    /**
     * “待确认收货订单” -查询订单列表
     *
     * @param headers Http头部信息
     * @param pageVO  接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<BuyerReceiveQueryVO>> pageToReceiveOrders(HttpHeaders headers, OrderValidatePageVO pageVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        Page<OrderDO> pageList = baseOrderService.pageBuyerOrders(loginUser.getMemberId(), loginUser.getMemberRoleId(), pageVO.getOrderNo(), pageVO.getDigest(), pageVO.getMemberName(), pageVO.getStartDate(), pageVO.getEndDate(), pageVO.getOrderType(), BuyerInnerStatusEnum.BUYER_TO_RECEIVE.getCode(), null, pageVO.getCurrent(), pageVO.getPageSize());
        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(order -> {
            BuyerReceiveQueryVO queryVO = new BuyerReceiveQueryVO();
            queryVO.setOrderId(order.getId());
            queryVO.setOrderNo(order.getOrderNo());
            queryVO.setCreateTime(order.getCreateTime().format(OrderServiceContants.DEFAULT_TIME_FORMATTER));
            queryVO.setDigest(order.getDigest());
            queryVO.setMemberName(order.getVendorMemberName());
            queryVO.setAmount(NumberUtil.formatAmount(order.getTotalAmount()));
            //显示最后一次的发货批次，即发货记录的条数
            queryVO.setBatchNo(order.getDeliveries().size());
            queryVO.setReceiptNo("");
            queryVO.setOrderType(order.getOrderType());
            queryVO.setOrderTypeName(OrderTypeEnum.getNameByCode(order.getOrderType()));
            queryVO.setInnerStatus(order.getBuyerInnerStatus());
            queryVO.setInnerStatusName(BuyerInnerStatusEnum.getNameByCode(order.getBuyerInnerStatus()));
            queryVO.setOuterStatus(order.getOuterStatus());
            queryVO.setOuterStatusName(OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * “待确认收货订单” -查询订单详情
     *
     * @param headers   Http头部信息
     * @param idVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BuyerOrderDetailVO> getToReceiveOrderDetails(HttpHeaders headers, OrderIdVO idVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        OrderDO order = orderRepository.findById(idVO.getOrderId()).orElse(null);
        if(order == null || !order.getBuyerMemberId().equals(loginUser.getMemberId()) || !order.getBuyerRoleId().equals(loginUser.getMemberRoleId())) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        return baseOrderService.getBuyerOrderDetail(order);
    }

    /**
     * “待确认收货订单” - 确认收货
     *
     * @param headers   Http头部信息
     * @param receiveVO 接口参数
     * @return 查询结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> receiveOrder(HttpHeaders headers, BuyerReceiveVO receiveVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return receiveOrder(loginUser.getUserName(), loginUser.getUserOrgName(), loginUser.getUserJobTitle(), loginUser.getMemberRoleName(), receiveVO.getOrderId(), receiveVO.getBatchNo(), receiveVO.getReceiveBill());
    }

    /**
     * “待确认收货订单” - 确认收货（此接口同时是： 自动收货功能调用的接口）
     *
     * @param userName         登录用户姓名
     * @param organizationName 组织机构名称
     * @param jobTitle         职位
     * @param roleName         会员角色名称
     * @param orderId         订单Id
     * @param batchNo          发货批次
     * @param receiveBill      收货回单url地址
     * @return                 查询结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> receiveOrder(String userName, String organizationName, String jobTitle, String roleName, Long orderId, Integer batchNo, String receiveBill) {
        OrderDO order = orderRepository.findById(orderId).orElse(null);
        if(order == null) {
            return Wrapper.fail(ResponseCode.ORDER_DOES_NOT_EXIST);
        }

        //Step 1: 校验发货条件
        Wrapper<TransferOrderReceiveBO> receiveCheckResult = baseOrderProductService.checkOrderReceive(order);
        if(receiveCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(receiveCheckResult.getCode(), receiveCheckResult.getMessage());
        }

        //Step 2: 当前订单收货
        Wrapper<Void> receiveResult = receiveOrder(userName, organizationName, jobTitle, roleName, order, batchNo, receiveBill);
        if(receiveResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(receiveResult.getCode(), receiveResult.getMessage());
        }

        //Step 3: 根据检查结果，判断是否要将转单后订单收货
        return receiveCheckResult.getData().getReceiveTransferredOrder() ? receiveOrder(userName, organizationName, jobTitle, roleName, receiveCheckResult.getData().getTransferredOrder(), batchNo, receiveBill) : Wrapper.success();
    }

    /**
     * “待确认收货订单” - 确认收货
     *
     * @param userName         登录用户姓名
     * @param organizationName 组织机构名称
     * @param jobTitle         职位
     * @param roleName         会员角色名称
     * @param order            订单
     * @param batchNo          发货批次
     * @param receiveBill      收货回单url地址
     * @return 收货结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> receiveOrder(String userName, String organizationName, String jobTitle, String roleName, OrderDO order, Integer batchNo, String receiveBill) {
        //Step 1 : 校验参数，修改发货记录统计数据
        Wrapper<OrderReceiveBO> checkResult = baseOrderDeliveryService.checkBuyerOrderReceive(order, batchNo, receiveBill);
        if(checkResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(checkResult.getCode(), checkResult.getMessage());
        }

        // 记录采购、供应的上一次内部状态，用于发送报表统计数据
        int lastBuyerInnerStatus = order.getBuyerInnerStatus();
        int lastVendorInnerStatus = order.getVendorInnerStatus();

        //Step 2 : 执行工作流任务（修改订单状态、记录内外流转记录）
        Wrapper<ProcessTaskBO> taskResult = baseOrderTaskService.execOrderProcess(order, checkResult.getData().getTaskJumpParamter());
        if(taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
        }

        //Step 3 : 收货全部完成之后有可能是支付环节，判断是否跳过支付环节
        if(checkResult.getData().getReceiveDone()) {
            Wrapper<OrderPaymentBO> jumpResult = baseOrderPaymentService.jumpOverOrderPaySerialTasks(order);
            if (jumpResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(jumpResult.getCode(), jumpResult.getMessage());
            }
        }
        // 添加完成时间
        if(order.getOuterStatus().equals(OrderOuterStatusEnum.ACCOMPLISHED.getCode())){
            order.setFinishTime(LocalDateTime.now());
        }
        orderRepository.saveAndFlush(order);

        //Step 4: 如果是Srm订单、采购请购单收货，发送收发货记录给结算服务
        baseOrderDeliveryService.notifySrmOrderReceive(order, batchNo);

        //Step 5 : 订单内、外流转记录
        baseOrderHistoryService.saveBuyerInnerHistory(order.getBuyerMemberId(), order.getBuyerRoleId(), userName, organizationName, jobTitle, order.getId(), order.getOrderNo(), OrderOperationEnum.CONFIRM_RECEIPT, order.getBuyerInnerStatus(), OrderStringEnum.RECEIPT_NUMBER.getName().concat(checkResult.getData().getReceiptNo()));
        baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), roleName, OrderOperationEnum.CONFIRM_RECEIPT, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), OrderStringEnum.RECEIPT_NUMBER.getName().concat(checkResult.getData().getReceiptNo()));

        //Step 6: 如果收货全部完成，向报表服务发送订单统计数据
        if(checkResult.getData().getReceiveDone()) {
            baseOrderService.reportBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(), lastBuyerInnerStatus, order.getBuyerInnerStatus());
            baseOrderService.reportVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(), lastVendorInnerStatus, order.getVendorInnerStatus());
        }

        //Step 7: 向消息服务发送采购商实时消息
        baseOrderService.messageBuyerOrder(order.getBuyerMemberId(), order.getBuyerRoleId(),order.getBuyerUserId(), order.getBuyerInnerStatus(), order.getOrderNo(), order.getDigest());
        baseOrderService.messageVendorOrder(order.getVendorMemberId(), order.getVendorRoleId(),order.getVendorUserId(), order.getVendorInnerStatus(), order.getOrderNo(), order.getDigest());

        //Step 8 : 订单完成后的操作
        baseOrderService.operateAfterOrderAccomplished(order);
        return Wrapper.success();
    }

    /**
     * 更新拼团订单状态
     *
     * @param userName         登录用户姓名
     * @param organizationName 组织机构名称
     * @param jobTitle         职位
     * @param roleName         会员角色名称
     * @param orderId         订单Id
     * @param promotionStatus 营销活动状态
     * @param groupId         拼团Id
     * @return 处理结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateGroupOrderStatus(String userName, String organizationName, String jobTitle, String roleName, Long orderId, OrderPromotionStatusEnum promotionStatus, Long groupId) {
        logger.info("开始处理拼团回调 => promotionStatus:" + promotionStatus.getName() + ", promotionCode:" + promotionStatus.getCode() + ", groupId:" + groupId);
        OrderDO order = orderRepository.findById(orderId).orElse(null);
        if(order == null) {
            return Wrapper.success();
        }

        //如果状态不是“等待通知”，返回
        if(!order.getPromotionStatus().equals(OrderPromotionStatusEnum.GROUP_WAITING_CONFIRM.getCode())) {
            logger.info("开始处理拼团回调 => 状态不是“等待通知”，返回");
            return Wrapper.success();
        }

        //更新状态和拼团Id
        order.setPromotionStatus(promotionStatus.getCode());
        order.setGroupId(NumberUtil.isNullOrZero(groupId) ? 0L : groupId);

        //如果订单拼团失败，取消订单
        if(promotionStatus.equals(OrderPromotionStatusEnum.GROUP_FAILED)) {
            order.setBuyerInnerStatus(BuyerInnerStatusEnum.CANCELLED.getCode());
            order.setVendorInnerStatus(VendorInnerStatusEnum.CANCELLED.getCode());
            order.setOuterStatus(OrderOuterStatusEnum.CANCELLED.getCode());
        }

        orderRepository.saveAndFlush(order);

        //如果是拼团失败，退款，返还库存
        if(promotionStatus.equals(OrderPromotionStatusEnum.GROUP_FAILED)) {
            //“拼团失败”的内、外流转记录
            baseOrderHistoryService.saveBuyerInnerHistory(order.getBuyerMemberId(), order.getBuyerRoleId(), userName, organizationName, jobTitle, order.getId(), order.getOrderNo(), OrderOperationEnum.GROUP_FAILED, order.getBuyerInnerStatus(), "");
            baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), roleName, OrderOperationEnum.GROUP_FAILED, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");

            Wrapper<Void> refundResult = baseOrderPaymentService.groupOrderRefund(order);
            logger.info("开始处理拼团回调 => 拼团失败，开始退款，code:" + refundResult.getCode() + ", msg:" + refundResult.getMessage());
            if(refundResult.getCode() == ResponseCode.SUCCESS.getCode()) {
                //“退款成功”的内、外流转记录
                baseOrderHistoryService.saveBuyerInnerHistory(order.getBuyerMemberId(), order.getBuyerRoleId(), userName, organizationName, jobTitle, order.getId(), order.getOrderNo(), OrderOperationEnum.REFUND, order.getBuyerInnerStatus(), OrderStringEnum.REFUND_SUCCESSFULLY.getName());
                baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), roleName, OrderOperationEnum.REFUND, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), OrderStringEnum.REFUND_SUCCESSFULLY.getName());

                //将订单未发货的数量返回库存
                Wrapper<Void> resumeResult = baseOrderService.resumeInventory(order);
                if (resumeResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                    logger.error("拼团失败后返还库存失败，code:" + resumeResult.getCode() + ", msg:" + resumeResult.getMessage());
                    return Wrapper.success();
                }
            } else {
                ////“退款失败”的内、外流转记录
                baseOrderHistoryService.saveBuyerInnerHistory(order.getBuyerMemberId(), order.getBuyerRoleId(), userName, organizationName, jobTitle, order.getId(), order.getOrderNo(), OrderOperationEnum.REFUND, order.getBuyerInnerStatus(), OrderStringEnum.REFUND_FAILED.getName());
                baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), roleName, OrderOperationEnum.REFUND, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), OrderStringEnum.REFUND_FAILED.getName());
            }

            //通知营销服务，返还营销活动、优惠券记录
            baseOrderService.resumePromotions(order);
        } else if(promotionStatus.equals(OrderPromotionStatusEnum.GROUP_SUCCESS)) {
            //“拼团成功”的内、外流转记录
            baseOrderHistoryService.saveBuyerInnerHistory(order.getBuyerMemberId(), order.getBuyerRoleId(), userName, organizationName, jobTitle, order.getId(), order.getOrderNo(), OrderOperationEnum.GROUP_SUCCESS, order.getBuyerInnerStatus(), "");
            baseOrderHistoryService.saveBuyerOrderOuterHistory(order.getId(), order.getOrderNo(), order.getBuyerMemberId(), order.getBuyerRoleId(), order.getBuyerMemberName(), roleName, OrderOperationEnum.GROUP_SUCCESS, order.getOuterStatus(), OrderOuterStatusEnum.getNameByCode(order.getOuterStatus()), "");
        }

        return Wrapper.success();
    }

    /**
     * 订单分页查询 - 通用 - 所有订单类型下拉框列表
     * @return 查询结果
     */
    @Override
    public Wrapper<List<DropdownItem>> getAllOrderType() {
        return Wrapper.success(baseOrderService.listOrderTypes());
    }

    /**
     * 提交订单 - 查询满额包邮的商品总运费
     * @param headers   HttpHeaders信息
     * @param freightVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<BigDecimal> findProductFreeFreight(HttpHeaders headers, OrderProductFreeFreightVO freightVO) {
        UserLoginCacheDTO loginUser = baseCacheService.needLoginFromBusinessPlatform(headers);
        return logisticsFeignService.findOrderFreeFreight(freightVO);
    }
}
